import snq from "snq";
import { Component, Input, OnInit, ViewChild } from "@angular/core";
import { FormArray, FormBuilder, FormGroup } from "@angular/forms";
import { LocalizationService, ConfigStateService } from '@abp/ng.core';
import { NzTableComponent } from 'ng-zorro-antd/table';
import { SegmentConfigrationDto, UniqueCodeSettingDto, UniqueCodeSettingService } from "../../proxy/joy/erp/basic-archives/core";
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { NzMessageService } from 'ng-zorro-antd/message';
import { SegmentConfigrationRefEntityComponent } from '../segment-configration-ref-entity/segment-configration-ref-entity.component';

@Component({
  selector: 'lib-unique-code-setting',
  templateUrl: './unique-code-setting.component.html',
  styleUrls: ['./unique-code-setting.component.less'],
})
export class UniqueCodeSettingComponent implements OnInit {
  @Input() settingKey: string;
  @ViewChild('basicTable') basicTable: NzTableComponent<any>;

  validateForm: FormGroup;
  uniqueCodeSetting: UniqueCodeSettingDto;
  tableData: any[] = [];
  
  get segmentConfigrations() {
    return this.validateForm.get('segmentConfigrations') as FormArray;
  }

  get segmentConfigrationsControls() {
    return this.segmentConfigrations?.controls;
  }

  get isFormChanged() {
    return snq(() => {
      let isFormChanged = false;
      for (var key of Object.keys(this.validateForm.value)) {
        if (this.validateForm.value[key] != this.uniqueCodeSetting[key]) {
          return true;
        }
      }
      return isFormChanged;
    });
  }
  
  constructor(
    private uniqueCodeSettingService: UniqueCodeSettingService,
    private fb: FormBuilder,
    public localizationService: LocalizationService,
    private modalRef: NzModalRef,
    private modal: NzModalService,
    private message: NzMessageService,
    public configState: ConfigStateService,
  ) {}

  ngOnInit(): void {
    this.validateForm = this.fb.group({
      autoCode: [false],
      segmentConfigrations: this.fb.array([])
    });
    this.getData();
  }


  private getData() {
    while (this.segmentConfigrations.length) {
      this.segmentConfigrations.removeAt(0);
    }

    this.uniqueCodeSettingService.get(this.settingKey).subscribe(result => {
      this.uniqueCodeSetting = result;

      if (result && result.segmentConfigrations) {
        result.segmentConfigrations.forEach(segmentConfigration => {
          this.segmentConfigrations.push(this.createSegmentConfigrationFormGroup(segmentConfigration));
        });
        this.updateTableData();
      }

      if (result.autoCode !== undefined) {
        this.validateForm.patchValue({ autoCode: result.autoCode });
      }
    });
  }

  private updateTableData() {
    this.tableData = [...this.segmentConfigrationsControls];
  }

  public createSegmentConfigrationFormGroup(segmentConfigration?: SegmentConfigrationDto): FormGroup {
    return this.fb.group({
      key: [segmentConfigration?.key],
      configration: [segmentConfigration?.configration]
    })
  }

  public addSegmentConfigration() {
    const modalRef = this.modal.create({
      nzTitle: this.l('BasicArchives::UI:UniqueCodeSetting.ModelTitle.SegmentConfigrations.Dialog.DialogTitle'),
      nzContent: SegmentConfigrationRefEntityComponent,
      nzWidth: 600,
      nzFooter: null
    });

    modalRef.afterClose.subscribe(result => {
      if (result) {
        this.segmentConfigrations.push(this.createSegmentConfigrationFormGroup(result));
        this.updateTableData();
      }
    });
  }

  public deleteSegmentConfigration(index: number) {
    this.segmentConfigrations.removeAt(index);
    this.updateTableData();
  }

  public editSegmentConfigration(index: number) {
    const segmentConfigration = this.segmentConfigrationsControls[index].value;
    
    const modalRef = this.modal.create({
      nzTitle: this.l('BasicArchives::UI:UniqueCodeSetting.ModelTitle.SegmentConfigrations.Dialog.DialogTitle'),
      nzContent: SegmentConfigrationRefEntityComponent,
      nzWidth: 600,
      nzFooter: null,
      nzComponentParams: {
        initialValue: segmentConfigration
      }
    });

    modalRef.afterClose.subscribe(result => {
      if (result) {
        this.segmentConfigrations.at(index).patchValue(result);
        this.updateTableData();
      }
    });
  }

  public submitForm() {
    if (this.validateForm.invalid || !this.isFormChanged) return;
  
    this.uniqueCodeSettingService.update(this.settingKey, this.validateForm.value)
      .subscribe(() => {
        this.message.success(this.l('BasicArchives::UI:UniqueCodeSetting.Message.Success'));
        
        // 刷新应用状态
        this.configState.refreshAppState();
      });
  }

  public cancel() {
    this.modalRef.close(false);
  }

  protected l(key: string, ...parmas: string[]): string {
    return this.localizationService.instant(key, ...parmas);
  }

  public getSegmentTypeDisplayName(segmentType: string) {
    return this.localizationService.instant(`BasicArchives::UI:UniqueCodeSetting.SegmentType.${segmentType}`);
  }
}